#include <iostream>
#include <string>
#include "Optional.hpp"

// 用于测试的简单类
class TestClass
{
public:
    TestClass(int v = 0) : value(v)
    {
        std::cout << "TestClass constructed with value " << value << std::endl;
    }
    ~TestClass()
    {
        std::cout << "TestClass destructed with value " << value << std::endl;
    }
    TestClass(const TestClass &other) : value(other.value)
    {
        std::cout << "TestClass copy constructed with value " << value << std::endl;
    }
    TestClass(TestClass &&other) noexcept : value(other.value)
    {
        std::cout << "TestClass move constructed with value " << value << std::endl;
        other.value = 0;
    }
    int getValue() const { return value; }

private:
    int value;
};

int main()
{
    std::cout << "\n=== 1. 基本构造和访问测试 ===" << std::endl;
    {
        // 默认构造
        Optional<int> empty;
        std::cout << "empty.isInit(): " << empty.isInit() << std::endl;

        // 使用值构造
        Optional<int> opt1(42);
        std::cout << "opt1.value: " << *opt1 << std::endl;

        // 使用bool操作符
        if (opt1)
        {
            std::cout << "opt1 is initialized" << std::endl;
        }
    }

    std::cout << "\n=== 2. 复制和移动测试 ===" << std::endl;
    {
        Optional<TestClass> opt1(TestClass(100));
        std::cout << "Original value: " << opt1->getValue() << std::endl;

        // 测试复制构造
        Optional<TestClass> opt2(opt1);
        std::cout << "Copied value: " << opt2->getValue() << std::endl;

        // 测试移动构造
        Optional<TestClass> opt3(std::move(opt1));
        std::cout << "Moved value: " << opt3->getValue() << std::endl;
    }

    std::cout << "\n=== 3. emplace测试 ===" << std::endl;
    {
        Optional<TestClass> opt;
        std::cout << "Before emplace: " << opt.isInit() << std::endl;

        // 使用emplace原地构造对象
        opt.emplace(200);
        std::cout << "After emplace, value: " << opt->getValue() << std::endl;
    }

    std::cout << "\n=== 4. 比较操作测试 ===" << std::endl;
    {
        Optional<int> opt1(10);
        Optional<int> opt2(20);
        Optional<int> opt3(10);
        Optional<int> empty;

        std::cout << "opt1 == opt3: " << (opt1 == opt3) << std::endl; // true
        std::cout << "opt1 < opt2: " << (opt1 < opt2) << std::endl;   // true
        std::cout << "empty < opt1: " << (empty < opt1) << std::endl; // true
    }

    std::cout << "\n=== 5. 异常处理测试 ===" << std::endl;
    {
        Optional<int> empty;
        try
        {
            // 尝试访问未初始化的Optional
            int value = *empty;
        }
        catch (const std::logic_error &e)
        {
            std::cout << "Caught exception: " << e.what() << std::endl;
        }
    }

    return 0;
}
